﻿#region Using directives

using System;
using System.Collections;
using System.Collections.Specialized;


using System.Web.Configuration;
using System.Data;
using System.Data.Common;
using System.Configuration.Provider;

using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;

using GPSTrackingServerDB.Entities;
using GPSTrackingServerDB.Data;
using GPSTrackingServerDB.Data.Bases;

#endregion

namespace GPSTrackingServerDB.Data.SqlClient
{
	/// <summary>
	/// This class is the Sql implementation of the NetTiersProvider.
	/// </summary>
	public sealed class SqlNetTiersProvider : GPSTrackingServerDB.Data.Bases.NetTiersProvider
	{
		private static object syncRoot = new Object();
		private string _applicationName;
        private string _connectionString;
        private bool _useStoredProcedure;
        string _providerInvariantName;
		
		/// <summary>
		/// Initializes a new instance of the <see cref="SqlNetTiersProvider"/> class.
		///</summary>
		public SqlNetTiersProvider()
		{	
		}		
		
		/// <summary>
        /// Initializes the provider.
        /// </summary>
        /// <param name="name">The friendly name of the provider.</param>
        /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
        /// <exception cref="T:System.ArgumentNullException">The name of the provider is null.</exception>
        /// <exception cref="T:System.InvalidOperationException">An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"></see> on a provider after the provider has already been initialized.</exception>
        /// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception>
		public override void Initialize(string name, NameValueCollection config)
        {
            // Verify that config isn't null
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            // Assign the provider a default name if it doesn't have one
            if (String.IsNullOrEmpty(name))
            {
                name = "SqlNetTiersProvider";
            }

            // Add a default "description" attribute to config if the
            // attribute doesn't exist or is empty
            if (string.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "NetTiers Sql provider");
            }

            // Call the base class's Initialize method
            base.Initialize(name, config);

            // Initialize _applicationName
            _applicationName = config["applicationName"];

            if (string.IsNullOrEmpty(_applicationName))
            {
                _applicationName = "/";
            }
            config.Remove("applicationName");


            #region "Initialize UseStoredProcedure"
            string storedProcedure  = config["useStoredProcedure"];
           	if (string.IsNullOrEmpty(storedProcedure))
            {
                throw new ProviderException("Empty or missing useStoredProcedure");
            }
            this._useStoredProcedure = Convert.ToBoolean(config["useStoredProcedure"]);
            config.Remove("useStoredProcedure");
            #endregion

			#region ConnectionString

			// Initialize _connectionString
			_connectionString = config["connectionString"];
			config.Remove("connectionString");

			string connect = config["connectionStringName"];
			config.Remove("connectionStringName");

			if ( String.IsNullOrEmpty(_connectionString) )
			{
				if ( String.IsNullOrEmpty(connect) )
				{
					throw new ProviderException("Empty or missing connectionStringName");
				}

				if ( DataRepository.ConnectionStrings[connect] == null )
				{
					throw new ProviderException("Missing connection string");
				}

				_connectionString = DataRepository.ConnectionStrings[connect].ConnectionString;
			}

            if ( String.IsNullOrEmpty(_connectionString) )
            {
                throw new ProviderException("Empty connection string");
			}

			#endregion
            
             #region "_providerInvariantName"

            // initialize _providerInvariantName
            this._providerInvariantName = config["providerInvariantName"];

            if (String.IsNullOrEmpty(_providerInvariantName))
            {
                throw new ProviderException("Empty or missing providerInvariantName");
            }
            config.Remove("providerInvariantName");

            #endregion

        }
		
		/// <summary>
		/// Creates a new <see cref="TransactionManager"/> instance from the current datasource.
		/// </summary>
		/// <returns></returns>
		public override TransactionManager CreateTransaction()
		{
			return new TransactionManager(this._connectionString);
		}
		
		/// <summary>
		/// Gets a value indicating whether to use stored procedure or not.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this repository use stored procedures; otherwise, <c>false</c>.
		/// </value>
		public bool UseStoredProcedure
		{
			get {return this._useStoredProcedure;}
			set {this._useStoredProcedure = value;}
		}
		
		 /// <summary>
        /// Gets or sets the connection string.
        /// </summary>
        /// <value>The connection string.</value>
		public string ConnectionString
		{
			get {return this._connectionString;}
			set {this._connectionString = value;}
		}
		
		/// <summary>
	    /// Gets or sets the invariant provider name listed in the DbProviderFactories machine.config section.
	    /// </summary>
	    /// <value>The name of the provider invariant.</value>
	    public string ProviderInvariantName
	    {
	        get { return this._providerInvariantName; }
	        set { this._providerInvariantName = value; }
	    }		
		
		///<summary>
		/// Indicates if the current <see cref="NetTiersProvider"/> implementation supports Transacton.
		///</summary>
		public override bool IsTransactionSupported
		{
			get
			{
				return true;
			}
		}

		
		#region "WebsiteLogProvider"
			
		private SqlWebsiteLogProvider innerSqlWebsiteLogProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="WebsiteLog"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override WebsiteLogProviderBase WebsiteLogProvider
		{
			get
			{
				if (innerSqlWebsiteLogProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlWebsiteLogProvider == null)
						{
							this.innerSqlWebsiteLogProvider = new SqlWebsiteLogProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlWebsiteLogProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlWebsiteLogProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlWebsiteLogProvider SqlWebsiteLogProvider
		{
			get {return WebsiteLogProvider as SqlWebsiteLogProvider;}
		}
		
		#endregion
		
		
		#region "UsersProvider"
			
		private SqlUsersProvider innerSqlUsersProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Users"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override UsersProviderBase UsersProvider
		{
			get
			{
				if (innerSqlUsersProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlUsersProvider == null)
						{
							this.innerSqlUsersProvider = new SqlUsersProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlUsersProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlUsersProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlUsersProvider SqlUsersProvider
		{
			get {return UsersProvider as SqlUsersProvider;}
		}
		
		#endregion
		
		
		#region "TrackDataProvider"
			
		private SqlTrackDataProvider innerSqlTrackDataProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="TrackData"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override TrackDataProviderBase TrackDataProvider
		{
			get
			{
				if (innerSqlTrackDataProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlTrackDataProvider == null)
						{
							this.innerSqlTrackDataProvider = new SqlTrackDataProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlTrackDataProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlTrackDataProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlTrackDataProvider SqlTrackDataProvider
		{
			get {return TrackDataProvider as SqlTrackDataProvider;}
		}
		
		#endregion
		
		
		#region "StatesProvider"
			
		private SqlStatesProvider innerSqlStatesProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="States"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override StatesProviderBase StatesProvider
		{
			get
			{
				if (innerSqlStatesProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlStatesProvider == null)
						{
							this.innerSqlStatesProvider = new SqlStatesProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlStatesProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlStatesProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlStatesProvider SqlStatesProvider
		{
			get {return StatesProvider as SqlStatesProvider;}
		}
		
		#endregion
		
		
		#region "RolesProvider"
			
		private SqlRolesProvider innerSqlRolesProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Roles"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override RolesProviderBase RolesProvider
		{
			get
			{
				if (innerSqlRolesProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlRolesProvider == null)
						{
							this.innerSqlRolesProvider = new SqlRolesProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlRolesProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlRolesProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlRolesProvider SqlRolesProvider
		{
			get {return RolesProvider as SqlRolesProvider;}
		}
		
		#endregion
		
		
		#region "RolesByUsersProvider"
			
		private SqlRolesByUsersProvider innerSqlRolesByUsersProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="RolesByUsers"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override RolesByUsersProviderBase RolesByUsersProvider
		{
			get
			{
				if (innerSqlRolesByUsersProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlRolesByUsersProvider == null)
						{
							this.innerSqlRolesByUsersProvider = new SqlRolesByUsersProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlRolesByUsersProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlRolesByUsersProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlRolesByUsersProvider SqlRolesByUsersProvider
		{
			get {return RolesByUsersProvider as SqlRolesByUsersProvider;}
		}
		
		#endregion
		
		
		#region "NotificationsLogProvider"
			
		private SqlNotificationsLogProvider innerSqlNotificationsLogProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="NotificationsLog"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override NotificationsLogProviderBase NotificationsLogProvider
		{
			get
			{
				if (innerSqlNotificationsLogProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlNotificationsLogProvider == null)
						{
							this.innerSqlNotificationsLogProvider = new SqlNotificationsLogProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlNotificationsLogProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlNotificationsLogProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlNotificationsLogProvider SqlNotificationsLogProvider
		{
			get {return NotificationsLogProvider as SqlNotificationsLogProvider;}
		}
		
		#endregion
		
		
		#region "NotificationsProvider"
			
		private SqlNotificationsProvider innerSqlNotificationsProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Notifications"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override NotificationsProviderBase NotificationsProvider
		{
			get
			{
				if (innerSqlNotificationsProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlNotificationsProvider == null)
						{
							this.innerSqlNotificationsProvider = new SqlNotificationsProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlNotificationsProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlNotificationsProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlNotificationsProvider SqlNotificationsProvider
		{
			get {return NotificationsProvider as SqlNotificationsProvider;}
		}
		
		#endregion
		
		
		#region "MqLogProvider"
			
		private SqlMqLogProvider innerSqlMqLogProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="MqLog"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override MqLogProviderBase MqLogProvider
		{
			get
			{
				if (innerSqlMqLogProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlMqLogProvider == null)
						{
							this.innerSqlMqLogProvider = new SqlMqLogProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlMqLogProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlMqLogProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlMqLogProvider SqlMqLogProvider
		{
			get {return MqLogProvider as SqlMqLogProvider;}
		}
		
		#endregion
		
		
		#region "ListenerLogProvider"
			
		private SqlListenerLogProvider innerSqlListenerLogProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="ListenerLog"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ListenerLogProviderBase ListenerLogProvider
		{
			get
			{
				if (innerSqlListenerLogProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlListenerLogProvider == null)
						{
							this.innerSqlListenerLogProvider = new SqlListenerLogProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlListenerLogProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlListenerLogProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlListenerLogProvider SqlListenerLogProvider
		{
			get {return ListenerLogProvider as SqlListenerLogProvider;}
		}
		
		#endregion
		
		
		#region "UsersByGroupsProvider"
			
		private SqlUsersByGroupsProvider innerSqlUsersByGroupsProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="UsersByGroups"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override UsersByGroupsProviderBase UsersByGroupsProvider
		{
			get
			{
				if (innerSqlUsersByGroupsProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlUsersByGroupsProvider == null)
						{
							this.innerSqlUsersByGroupsProvider = new SqlUsersByGroupsProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlUsersByGroupsProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlUsersByGroupsProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlUsersByGroupsProvider SqlUsersByGroupsProvider
		{
			get {return UsersByGroupsProvider as SqlUsersByGroupsProvider;}
		}
		
		#endregion
		
		
		#region "ImeiTypeProvider"
			
		private SqlImeiTypeProvider innerSqlImeiTypeProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="ImeiType"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ImeiTypeProviderBase ImeiTypeProvider
		{
			get
			{
				if (innerSqlImeiTypeProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlImeiTypeProvider == null)
						{
							this.innerSqlImeiTypeProvider = new SqlImeiTypeProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlImeiTypeProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlImeiTypeProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlImeiTypeProvider SqlImeiTypeProvider
		{
			get {return ImeiTypeProvider as SqlImeiTypeProvider;}
		}
		
		#endregion
		
		
		#region "ImeiProvider"
			
		private SqlImeiProvider innerSqlImeiProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Imei"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ImeiProviderBase ImeiProvider
		{
			get
			{
				if (innerSqlImeiProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlImeiProvider == null)
						{
							this.innerSqlImeiProvider = new SqlImeiProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlImeiProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlImeiProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlImeiProvider SqlImeiProvider
		{
			get {return ImeiProvider as SqlImeiProvider;}
		}
		
		#endregion
		
		
		#region "GroupsProvider"
			
		private SqlGroupsProvider innerSqlGroupsProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Groups"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GroupsProviderBase GroupsProvider
		{
			get
			{
				if (innerSqlGroupsProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGroupsProvider == null)
						{
							this.innerSqlGroupsProvider = new SqlGroupsProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGroupsProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlGroupsProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGroupsProvider SqlGroupsProvider
		{
			get {return GroupsProvider as SqlGroupsProvider;}
		}
		
		#endregion
		
		
		#region "GpsModelsProvider"
			
		private SqlGpsModelsProvider innerSqlGpsModelsProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="GpsModels"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GpsModelsProviderBase GpsModelsProvider
		{
			get
			{
				if (innerSqlGpsModelsProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGpsModelsProvider == null)
						{
							this.innerSqlGpsModelsProvider = new SqlGpsModelsProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGpsModelsProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlGpsModelsProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGpsModelsProvider SqlGpsModelsProvider
		{
			get {return GpsModelsProvider as SqlGpsModelsProvider;}
		}
		
		#endregion
		
		
		#region "GeoFenceDetailsProvider"
			
		private SqlGeoFenceDetailsProvider innerSqlGeoFenceDetailsProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="GeoFenceDetails"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GeoFenceDetailsProviderBase GeoFenceDetailsProvider
		{
			get
			{
				if (innerSqlGeoFenceDetailsProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGeoFenceDetailsProvider == null)
						{
							this.innerSqlGeoFenceDetailsProvider = new SqlGeoFenceDetailsProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGeoFenceDetailsProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlGeoFenceDetailsProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGeoFenceDetailsProvider SqlGeoFenceDetailsProvider
		{
			get {return GeoFenceDetailsProvider as SqlGeoFenceDetailsProvider;}
		}
		
		#endregion
		
		
		#region "GeoFenceByImeiProvider"
			
		private SqlGeoFenceByImeiProvider innerSqlGeoFenceByImeiProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="GeoFenceByImei"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GeoFenceByImeiProviderBase GeoFenceByImeiProvider
		{
			get
			{
				if (innerSqlGeoFenceByImeiProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGeoFenceByImeiProvider == null)
						{
							this.innerSqlGeoFenceByImeiProvider = new SqlGeoFenceByImeiProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGeoFenceByImeiProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlGeoFenceByImeiProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGeoFenceByImeiProvider SqlGeoFenceByImeiProvider
		{
			get {return GeoFenceByImeiProvider as SqlGeoFenceByImeiProvider;}
		}
		
		#endregion
		
		
		#region "NotificationsByImeiProvider"
			
		private SqlNotificationsByImeiProvider innerSqlNotificationsByImeiProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="NotificationsByImei"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override NotificationsByImeiProviderBase NotificationsByImeiProvider
		{
			get
			{
				if (innerSqlNotificationsByImeiProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlNotificationsByImeiProvider == null)
						{
							this.innerSqlNotificationsByImeiProvider = new SqlNotificationsByImeiProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlNotificationsByImeiProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlNotificationsByImeiProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlNotificationsByImeiProvider SqlNotificationsByImeiProvider
		{
			get {return NotificationsByImeiProvider as SqlNotificationsByImeiProvider;}
		}
		
		#endregion
		
		
		#region "GeoFenceProvider"
			
		private SqlGeoFenceProvider innerSqlGeoFenceProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="GeoFence"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GeoFenceProviderBase GeoFenceProvider
		{
			get
			{
				if (innerSqlGeoFenceProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGeoFenceProvider == null)
						{
							this.innerSqlGeoFenceProvider = new SqlGeoFenceProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGeoFenceProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlGeoFenceProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGeoFenceProvider SqlGeoFenceProvider
		{
			get {return GeoFenceProvider as SqlGeoFenceProvider;}
		}
		
		#endregion
		
		
		#region "PendingComandProvider"
			
		private SqlPendingComandProvider innerSqlPendingComandProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="PendingComand"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override PendingComandProviderBase PendingComandProvider
		{
			get
			{
				if (innerSqlPendingComandProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlPendingComandProvider == null)
						{
							this.innerSqlPendingComandProvider = new SqlPendingComandProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlPendingComandProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlPendingComandProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlPendingComandProvider SqlPendingComandProvider
		{
			get {return PendingComandProvider as SqlPendingComandProvider;}
		}
		
		#endregion
		
		
		#region "GasPricesProvider"
			
		private SqlGasPricesProvider innerSqlGasPricesProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="GasPrices"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GasPricesProviderBase GasPricesProvider
		{
			get
			{
				if (innerSqlGasPricesProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGasPricesProvider == null)
						{
							this.innerSqlGasPricesProvider = new SqlGasPricesProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGasPricesProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlGasPricesProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGasPricesProvider SqlGasPricesProvider
		{
			get {return GasPricesProvider as SqlGasPricesProvider;}
		}
		
		#endregion
		
		
		#region "CountriesProvider"
			
		private SqlCountriesProvider innerSqlCountriesProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Countries"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override CountriesProviderBase CountriesProvider
		{
			get
			{
				if (innerSqlCountriesProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlCountriesProvider == null)
						{
							this.innerSqlCountriesProvider = new SqlCountriesProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlCountriesProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlCountriesProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlCountriesProvider SqlCountriesProvider
		{
			get {return CountriesProvider as SqlCountriesProvider;}
		}
		
		#endregion
		
		
		#region "CitiesProvider"
			
		private SqlCitiesProvider innerSqlCitiesProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Cities"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override CitiesProviderBase CitiesProvider
		{
			get
			{
				if (innerSqlCitiesProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlCitiesProvider == null)
						{
							this.innerSqlCitiesProvider = new SqlCitiesProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlCitiesProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlCitiesProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlCitiesProvider SqlCitiesProvider
		{
			get {return CitiesProvider as SqlCitiesProvider;}
		}
		
		#endregion
		
		
		#region "AdminRolesByAdminProvider"
			
		private SqlAdminRolesByAdminProvider innerSqlAdminRolesByAdminProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="AdminRolesByAdmin"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AdminRolesByAdminProviderBase AdminRolesByAdminProvider
		{
			get
			{
				if (innerSqlAdminRolesByAdminProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAdminRolesByAdminProvider == null)
						{
							this.innerSqlAdminRolesByAdminProvider = new SqlAdminRolesByAdminProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAdminRolesByAdminProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlAdminRolesByAdminProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAdminRolesByAdminProvider SqlAdminRolesByAdminProvider
		{
			get {return AdminRolesByAdminProvider as SqlAdminRolesByAdminProvider;}
		}
		
		#endregion
		
		
		#region "TrackDataLastLocationProvider"
			
		private SqlTrackDataLastLocationProvider innerSqlTrackDataLastLocationProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="TrackDataLastLocation"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override TrackDataLastLocationProviderBase TrackDataLastLocationProvider
		{
			get
			{
				if (innerSqlTrackDataLastLocationProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlTrackDataLastLocationProvider == null)
						{
							this.innerSqlTrackDataLastLocationProvider = new SqlTrackDataLastLocationProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlTrackDataLastLocationProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlTrackDataLastLocationProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlTrackDataLastLocationProvider SqlTrackDataLastLocationProvider
		{
			get {return TrackDataLastLocationProvider as SqlTrackDataLastLocationProvider;}
		}
		
		#endregion
		
		
		#region "AdminRolesProvider"
			
		private SqlAdminRolesProvider innerSqlAdminRolesProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="AdminRoles"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AdminRolesProviderBase AdminRolesProvider
		{
			get
			{
				if (innerSqlAdminRolesProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAdminRolesProvider == null)
						{
							this.innerSqlAdminRolesProvider = new SqlAdminRolesProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAdminRolesProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlAdminRolesProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAdminRolesProvider SqlAdminRolesProvider
		{
			get {return AdminRolesProvider as SqlAdminRolesProvider;}
		}
		
		#endregion
		
		
		#region "GroupsByImeiProvider"
			
		private SqlGroupsByImeiProvider innerSqlGroupsByImeiProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="GroupsByImei"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GroupsByImeiProviderBase GroupsByImeiProvider
		{
			get
			{
				if (innerSqlGroupsByImeiProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGroupsByImeiProvider == null)
						{
							this.innerSqlGroupsByImeiProvider = new SqlGroupsByImeiProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGroupsByImeiProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlGroupsByImeiProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGroupsByImeiProvider SqlGroupsByImeiProvider
		{
			get {return GroupsByImeiProvider as SqlGroupsByImeiProvider;}
		}
		
		#endregion
		
		
		#region "AdminProvider"
			
		private SqlAdminProvider innerSqlAdminProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Admin"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AdminProviderBase AdminProvider
		{
			get
			{
				if (innerSqlAdminProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAdminProvider == null)
						{
							this.innerSqlAdminProvider = new SqlAdminProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAdminProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <see cref="SqlAdminProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAdminProvider SqlAdminProvider
		{
			get {return AdminProvider as SqlAdminProvider;}
		}
		
		#endregion
		
		
		
		#region "General data access methods"

		#region "ExecuteNonQuery"
		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		public override void ExecuteNonQuery(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			database.ExecuteNonQuery(commandWrapper);	
			
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		public override void ExecuteNonQuery(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			database.ExecuteNonQuery(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(commandType, commandText);	
		}
		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteNonQuery(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteDataReader"
		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteReader(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteReader(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteReader(commandWrapper);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteReader(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteReader(commandType, commandText);	
		}
		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteReader(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteDataSet"
		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteDataSet(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteDataSet(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteDataSet(commandWrapper);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteDataSet(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteDataSet(commandType, commandText);	
		}
		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteDataSet(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteScalar"
		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override object ExecuteScalar(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteScalar(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteScalar(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override object ExecuteScalar(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteScalar(commandWrapper);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteScalar(commandWrapper, transactionManager.TransactionObject);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override object ExecuteScalar(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteScalar(commandType, commandText);	
		}
		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteScalar(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#endregion


	}
}
